import json
from typing import Any

from zkl_pyutils_serialization.basics import get_context_tag_value
from zkl_pyutils_serialization.convert import convert, registry
from zkl_pyutils_serialization.convertors.common import PyObjectFormat
from zkl_pyutils_serialization.tags import DstFormat, DstTypehint, SrcFormat
from .format import JsonStringFormat, JsonValueFormat
from .typing import JsonValue


@registry.register({SrcFormat: JsonValueFormat, DstFormat: JsonStringFormat})
def json_value_to_json_string_convertor(value: JsonValue) -> str:
    return json.dumps(value)


@registry.register({SrcFormat: JsonStringFormat, DstFormat: JsonValueFormat})
def json_string_to_json_value_convertor(value: JsonValue) -> str:
    return json.loads(value)


@registry.register({SrcFormat: PyObjectFormat, DstFormat: JsonStringFormat})
def python_object_to_json_string_convertor(value: Any) -> str:
    dst_typehint = get_context_tag_value(DstTypehint)
    value = convert(value, src_format=PyObjectFormat, dst_format=JsonValueFormat)
    value = convert(value, src_format=JsonValueFormat, dst_format=JsonStringFormat, dst_typehint=dst_typehint)
    return value


@registry.register({SrcFormat: JsonStringFormat, DstFormat: PyObjectFormat})
def json_string_to_python_object_convertor(value: str) -> Any:
    dst_typehint = get_context_tag_value(DstTypehint)
    value = convert(value, src_format=JsonStringFormat, dst_format=JsonValueFormat)
    value = convert(value, src_format=JsonValueFormat, dst_format=PyObjectFormat, dst_typehint=dst_typehint)
    return value
